using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Alidns20150109;
using AlibabaCloud.SDK.Alidns20150109.Models;
using Furion;
using Furion.JsonSerialization;
using Furion.RemoteRequest.Extensions;
using Furion.TaskScheduler;
using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using System.Net;
using System.Text.RegularExpressions;
using Tea;

namespace AliyunDDNS
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private string? lastIp = "";
        private string? currentIp = "";
        private string? ipAddress = "";

        private const string WorkName_ListenIpChang = "ListenIpChange";
        private Client? client = null;
        private async void Form1_Load(object sender, EventArgs e)
        {
            //http://checkip.dyndns.com/
            //监听IP变化

            //将程序从任务栏移除显示
            ShowInTaskbar = false;
            //隐藏窗口
            Visible = false;
            //显示托盘图标
            notifyIcon1.Visible = true;

            var domains = App.Configuration["domains"];
            textBox1.Text = domains;

            await CheckIp();
            SpareTime.Do(1000 * 60 * 5, (timer, count) =>
            {
                _ = CheckIp();
            }, WorkName_ListenIpChang, startNow: true);
        }

        private async Task CheckIp(bool forceUpdate = false)
        {
            try
            {
                ////https://ip.cn/api/index?ip=&type=0 

                ////var data = await "https://ip.tool.lu".GetAsStringAsync();
                ////currentIp = new Regex("(?<=当前IP: ).*?(?=\r)", RegexOptions.Singleline).Match(data)?.Value;
                ////ipAddress = new Regex("(?<=归属地: ).*?(?=\r)", RegexOptions.Singleline).Match(data)?.Value;

                //var data = await "https://ip.cn/api/index?ip=&type=0 ".GetAsStringAsync();
                //currentIp = new Regex("(?<=ip\":\").*?(?=\")", RegexOptions.Singleline).Match(data)?.Value;
                //ipAddress = new Regex("(?<=address\":\").*?(?=\")", RegexOptions.Singleline).Match(data)?.Value;

                var result = await GetIp();
                currentIp = result.Item1;
                ipAddress = result.Item2;
                label1.Text = currentIp;
                label2.Text = ipAddress;
                label3.Text = DateTime.Now.ToString("更新时间：HH:mm");
                if (forceUpdate)
                {
                    _ = HandleDDns();
                }
                else if (currentIp != lastIp)
                {
                    AddLog($"【信息】IP{(string.IsNullOrWhiteSpace(lastIp) ? "" : $"由")}变为{currentIp}，即将自动解析");
                    _ = HandleDDns();
                }
            }
            catch (Exception)
            {
                AddLog($"【错误】获取本机IP异常，3秒后重试");
                await Task.Delay(30000);
                _ = CheckIp();
            }

        }



        private async Task<Tuple<string, string>> GetIp()
        {
            var ip = "";
            var address = "";
            //try
            //{
            //    //https://ip.cn/api/index?ip=&type=0 

            //    //var data = await "https://ip.tool.lu".GetAsStringAsync();
            //    //currentIp = new Regex("(?<=当前IP: ).*?(?=\r)", RegexOptions.Singleline).Match(data)?.Value;
            //    //ipAddress = new Regex("(?<=归属地: ).*?(?=\r)", RegexOptions.Singleline).Match(data)?.Value;
            //    var data = await "https://forge.speedtest.cn/api/location/info".GetAsStringAsync();
            //    ip = new Regex("(?<=ip\":\").*?(?=\")", RegexOptions.Singleline).Match(data)?.Value;
            //    address = new Regex("(?<=city\":\").*?(?=\")", RegexOptions.Singleline).Match(data)?.Value;
            //    address = Regex.Unescape(address ?? "");
            //}
            //catch (Exception)
            //{
            //}

            if (string.IsNullOrWhiteSpace(ip))
            {
                try
                {
                    var data = await "https://2024.ip138.com".GetAsStringAsync();
                    ip = new Regex("(?<=您的IP地址是：).*?(?=<)", RegexOptions.Singleline).Match(data)?.Value;
                    address = new Regex("(?<=来自：).*?(?=<)", RegexOptions.Singleline).Match(data)?.Value;
                }
                catch (Exception)
                {
                }
            }
            if (string.IsNullOrWhiteSpace(ip))
            {
                try
                {
                    var data = await "https://tool.lu/ip/".GetAsStringAsync();
                    ip = new Regex("(?<=你的外网IP地址是：).*?(?=<)", RegexOptions.Singleline).Match(data)?.Value;
                    address = "";
                }
                catch (Exception)
                {
                }
            }

            if (string.IsNullOrWhiteSpace(ip))
            {
                try
                {
                    var data = await "https://zh-hans.ipshu.com/myip_info?random=1".GetAsStringAsync();
                    ip = new Regex("(?<=复制:).*?(?=\")", RegexOptions.Singleline).Match(data)?.Value;
                    address = "";// new Regex("(?<=city\":\").*?(?=\")", RegexOptions.Singleline).Match(data)?.Value;                
                }
                catch (Exception)
                {
                }
            }
        
            if (string.IsNullOrWhiteSpace(ip))
            {
                throw new Exception("IP获取失败");
            }
            return new Tuple<string, string>(ip?.Trim() ?? "", address?.Trim() ?? "");


        }

        private async void toolStripButton1_Click(object sender, EventArgs e)
        {
            var f = new FormAccesskey();
            if (f.ShowDialog() == DialogResult.Yes)
            {
                //配置文件通过事件总线异步更新，此处延迟防止未更新完成
                AddLog($"【信息】正在重载配置文件");
                await Task.Delay(500);
                App.Configuration.Reload();
                _ = CheckIp(true);
            }

        }

        private async Task HandleDDns()
        {
            if (string.IsNullOrWhiteSpace(currentIp))
            {
                AddLog($"【异常】公网IP获取失败");
                return;
            }
            var key = App.Configuration["accessKey"];
            var secret = App.Configuration["accessKeySecret"];
            if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(secret))
            {
                AddLog($"【异常】请先设置AccessKeyId和AccessKeySecret");
                return;
            }
            var domains = textBox1.Lines.Where(x => !string.IsNullOrWhiteSpace(x));
            if (domains.Count() == 0)
            {
                AddLog($"【异常】请在右侧填入需要解析的域名");
                return;
            }
            lastIp = currentIp;
            client = CreateClient(key, secret);
            foreach (var domain in domains)
            {
                if (string.IsNullOrWhiteSpace(domain.Trim())) continue;
                //获取域名
                var dArray = domain.Split('.');
                //一级域名
                var domainName = $"{dArray[dArray.Length - 2]}.{dArray[dArray.Length - 1]}";
                //主机记录  如果要解析@.exmaple.com，主机记录要填写”@”，而不是空。
                var rr = domain.Replace(domainName, "").TrimEnd('.');

                await DeleteSubDomainRecordsWithOptionsAsync(new DeleteSubDomainRecordsRequest
                {
                    DomainName = domainName,
                    RR = rr,
                });


                await AddDomainRecordWithOptions(new AddDomainRecordRequest
                {
                    DomainName = domainName,
                    RR = rr,
                    //RR值可为空，即@解析；不允许含有下划线；
                    Type = "A",
                    Value = currentIp
                });
            }
        }


        private void AddLog(string message)
        {
            if (textBox2.Lines.Length > 100) textBox2.Clear();
            var msg = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss} => {message}{Environment.NewLine}";
            textBox2.AppendText(msg);
        }

        /// <summary>
        /// 删除域名
        /// </summary>
        /// <param name="request"></param> 
        private async Task<bool> DeleteSubDomainRecordsWithOptionsAsync(DeleteSubDomainRecordsRequest request)
        {
            var domain = $"{request.RR}.{request.DomainName}";
            var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            try
            {
                var result = await client.DeleteSubDomainRecordsWithOptionsAsync(request, runtime);
                if (result.Body.TotalCount != "0")
                {
                    //删除域名成功
                    AddLog($"【成功】删除{domain}域名");
                    return true;
                }
            }
            catch (TeaException error)
            {
                AddLog($"【异常】删除{domain}域名失败，原因：{error.Message}");
            }
            return false;
        }


        private async Task<bool> AddDomainRecordWithOptions(AddDomainRecordRequest request)
        {
            var domain = $"{request.RR}.{request.DomainName}";
            var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            try
            {
                var result = await client.AddDomainRecordWithOptionsAsync(request, runtime);
                if (string.IsNullOrWhiteSpace(result.Body.RecordId))
                {
                    AddLog($"【失败】{domain}域名解析失败");
                    return false;
                }
                //域名解析成功
                AddLog($"【成功】{domain}已解析到{request.Value}");
                return true;
            }
            catch (TeaException error)
            {
                AddLog($"【异常】{domain}域名解析失败，原因：{error.Message}");
            }
            return false;
        }


        private Client CreateClient(string accessKeyId, string accessKeySecret)
        {
            var config = new Config
            {
                // 您的 AccessKey ID
                AccessKeyId = accessKeyId,
                // 您的 AccessKey Secret
                AccessKeySecret = accessKeySecret,
            };
            // 访问的域名
            config.Endpoint = "alidns.cn-hangzhou.aliyuncs.com";
            return new Client(config);
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            _ = CheckIp(true);
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            var f = new FormHelp();
            f.Show();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            var json = JSON.Serialize(new
            {
                domains = textBox1.Text
            });
            File.WriteAllText("domainsetting.json", json);
            App.Configuration.Reload();
            _ = CheckIp(true);
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            Process.Start("explorer.exe", "https://gitee.com/skywolf627/aliyun-ddns");
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //设置程序允许显示在任务栏
            ShowInTaskbar = true;
            //设置窗口可见
            Visible = true;
            //设置窗口状态
            WindowState = FormWindowState.Normal;
            //设置窗口为活动状态，防止被其他窗口遮挡。
            Activate();
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                //将程序从任务栏移除显示
                ShowInTaskbar = false;
                //隐藏窗口
                Visible = false;
                //显示托盘图标
                notifyIcon1.Visible = true;

            }
        }
    }
}